#pragma once
#include <memory>
#include "Connect.hpp"
#include "Socket.hpp"
#include "Log.hpp"
#include "NormalConnect.hpp"
#include "NonBlock.hpp"

namespace ListenConnectModule
{
    using namespace ConnectModule;
    using namespace NormalConnectModule;
    using namespace SocketModule;
    using namespace LogModule;
    using namespace NonBlockModule;

    class ListenConnect : public Connect
    {
    public:
        ListenConnect(uint16_t port) : _listensockfd(std::make_unique<TcpSocket>()), _port(port)
        {
            _listensockfd->BuildTcpSocketMethod(_port);
            SetEvents(EPOLLIN | EPOLLET);
            SetFd(_listensockfd->Fd());
        }
        virtual void Recv() override
        {
            while (true)
            {
                int outerrno;
                int fd = _listensockfd->Accepter(nullptr, &outerrno);
                if (fd > 0)
                {
                    // 读取到就绪的文件描述符
                    LOG(LogLevel::DEBUG) << "accetper connection success,fd is " << fd;
                    // 将新获得的文件描述符添加到epoll模型中
                    std::shared_ptr<NormalConnect> normalconn = std::make_shared<NormalConnect>(fd);
                    Owner()->BuiltConnection(normalconn);
                }
                else
                {
                    if (outerrno == EAGAIN || outerrno == EWOULDBLOCK)
                    {
                        LOG(LogLevel::DEBUG) << "accetper all connection ... done";
                        break;
                    }
                    else if (outerrno == EINTR)
                    {
                        LOG(LogLevel::DEBUG) << "accetper intr by signal, continue";
                        continue;
                    }
                    else
                    {
                        LOG(LogLevel::WARNING) << "accetper error ... Ignore";
                        break;
                    }
                }
            }
        }

        virtual void Send() override
        {}
        virtual void Except() override
        {}

        virtual ~ListenConnect()
        {}

    private:
        std::unique_ptr<TcpSocket> _listensockfd;
        uint16_t _port;
    };

}